package com.Jano.service.impl;/**
 * @ClassName : JwtServiceImpl
 * @Description : 刷新令牌的实现类
 * @Author : Jano
 * @Date: 2022-07-16 17:07
 */

import com.Jano.dto.JsonResult;
import com.Jano.model.UserModel;
import com.Jano.service.JwtService;
import com.Jano.service.UserService;
import com.Jano.util.jwt.Constant;
import com.Jano.util.jwt.JwtTokenUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 刷新令牌的实现类
 *
 * @author zoumaoji
 * @date 2022/07/16 17:07
 **/
@Service
public class JwtServiceImpl extends AbstractBaseServiceImpl implements JwtService {
    @Autowired
    UserService userService;

    /**
     * 刷新令牌的逻辑
     * 刷新用户的信息、刷新令牌的过期时间
     * @param refreshToken
     * @return com.Jano.dto.JsonResult
     * @author zoumaoji
     * @date 2022/07/16 17:08
     */
    @Override
    public JsonResult refreshToken(String refreshToken,HttpSession session) {
        JsonResult jsonResult = new JsonResult();
        //获取刷新令牌中用户的信息
        // 1.判断refreshToken是否为空
        if (StringUtils.isBlank(refreshToken)) {
            //未经授权的状态码 未携带refreshToken的情况
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setErrMsg("please login!！");
            return jsonResult;
        }
        // 2.refreshToken看是否合法
        Logger logger = LoggerFactory.getLogger(getClass());
        logger.debug("当前刷新令牌是否合法"+JwtTokenUtil.getClaimsFromToken(refreshToken).toString());

        if (Objects.isNull(JwtTokenUtil.getClaimsFromToken(refreshToken))) {
            //未经授权的状态码 token非法的情况
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setErrMsg("token invalid!!");
            return jsonResult;
        }

        //3.判断刷新令牌是否过期了,在拦截器中我们已经对ACCESS_TOKEN进行了拦截判断过期情况校验
        //对于刷新令牌的这个接口就不进行拦截了
        if (JwtTokenUtil.isTokenExpired(refreshToken)) {
            jsonResult.setCode(HttpStatus.REQUEST_TIMEOUT.value());
            jsonResult.setErrMsg("refreshToken expired!!");
            return jsonResult;
        }
        logger.debug("当前刷新令牌是否过期"+JwtTokenUtil.isTokenExpired(refreshToken).toString());
        //4.判断用户信息是否更新(我在这里的做法就不再比较了直接根据用户id查数据库用户信息)
        //⚠️：当我们为一个用户修改了用户名等信息token是需要刷新的,因为如果不刷新在拦截器进行
        //权限判定的时候我们是根据用户名查找数据库获取当前用户的权限的那么修改之后以前的用户名
        //就不生效了，所以这里刷新的时候一定要拿到最新的用户信息(‼️数据库表用户名我设计的是唯一的)
        String userId = JwtTokenUtil.getUserId(refreshToken);
        UserModel user = userService.findById(Integer.valueOf(userId));
        Map<String, Object> claims =new HashMap<>();
        claims.put(Constant.JWT_USER_NAME, user.getUsername());
        //最终刷新后的结果
        String refreshTokenResult = JwtTokenUtil.refreshToken(refreshToken, claims);
        jsonResult.setCode(HttpStatus.OK.value());
        jsonResult.setData(refreshTokenResult);
        //记录一下当前操作的用户,放在session中供Aop切面日志获取
        session.setAttribute("sessionUser",user);
        return jsonResult;
    }
}
